package com.sc.service.impl;

import com.mybatisflex.core.update.UpdateWrapper;
import com.mybatisflex.core.util.UpdateEntity;
import com.mybatisflex.spring.service.impl.CacheableServiceImpl;
import com.sc.dto.ClazzMappingUpdateDTO;
import com.sc.entity.ClazzCourse;
import com.sc.entity.Course;
import com.sc.mapper.CourseMapper;
import com.sc.service.ClazzCourseService;
import com.sc.service.CourseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 课程表 服务层实现。
 *
 * @author JoeZhou
 * @since 2024-09-14
 */
@Service

@CacheConfig(cacheNames = "course")
public class CourseServiceImpl extends CacheableServiceImpl<CourseMapper, Course> implements CourseService {

    @Autowired
    private ClazzCourseService clazzCourseService;
    @Override
    @CacheEvict(allEntries = true)
    public boolean remove(QueryWrapper query) {
        return super.remove(query);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean removeByIds(Collection<? extends Serializable> ids) {
        return super.removeByIds(ids);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean save(Course entity) {
        return super.save(entity);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean update(Course entity, QueryWrapper query) {
        return super.update(entity, query);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean updateById(Course entity, boolean ignoreNulls) {
        return super.updateById(entity, ignoreNulls);
    }

    @Override
    @CacheEvict(allEntries = true)
    public boolean updateBatch(Collection<Course> entities, int batchSize) {
        return super.updateBatch(entities, batchSize);
    }

    @Override
    @Cacheable(key = "#id")
    public Course getById(Serializable id) {
        return super.getById(id);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public Course getOne(QueryWrapper query) {
        return super.getOne(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public <R> R getOneAs(QueryWrapper query, Class<R> asType) {
        return super.getOneAs(query, asType);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public Object getObj(QueryWrapper query) {
        return super.getObj(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public <R> R getObjAs(QueryWrapper query, Class<R> asType) {
        return super.getObjAs(query, asType);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public List<Object> objList(QueryWrapper query) {
        return super.objList(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public <R> List<R> objListAs(QueryWrapper query, Class<R> asType) {
        return super.objListAs(query, asType);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public List<Course> list(QueryWrapper query) {
        return super.list(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public <R> List<R> listAs(QueryWrapper query, Class<R> asType) {
        return super.listAs(query, asType);
    }

    /**
     * @deprecated 无法通过注解进行缓存操作。
     */
    @Override
    @Deprecated
    public List<Course> listByIds(Collection<? extends Serializable> ids) {
        return super.listByIds(ids);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
    public long count(QueryWrapper query) {
        return super.count(query);
    }

    @Override
    @Cacheable(key = "#root.methodName + ':' + #page.getPageSize() + ':' + #page.getPageNumber() + ':' + #query.toSQL()")
    public <R> Page<R> pageAs(Page<R> page, QueryWrapper query, Class<R> asType) {
        Page<R> page1 = super.pageAs(page, query, asType);
        QueryWrapper queryWrapper = QueryWrapper.create();
        for (R record : page1.getRecords()) {
            Course course = (Course) record;
            queryWrapper.clear();
            queryWrapper.select("clazz_id");
            queryWrapper.eq("course_id", course.getId());
            course.setMapClazzIds(clazzCourseService.listAs(queryWrapper, Long.class));
        }
        return page1;
    }

    @Override
    @CacheEvict(allEntries = true)
    @Transactional
    public boolean updateClazzMapping(ClazzMappingUpdateDTO dto) {
        Course course = this.getById(dto.getCourseId());
        course.setMapGradeList(String.join(",", dto.getMapGradeList()));
        QueryWrapper queryWrapper = QueryWrapper.create().eq("course_id", dto.getCourseId());
        // 删除原来映射的班级
        clazzCourseService.remove(queryWrapper);
        // 更新映射的年级
        this.updateById(course, true);
        List<ClazzCourse> list = new ArrayList<>();
        dto.getMapClazzList().forEach(clazzId -> {
            list.add(new ClazzCourse(course.getId(), clazzId));
        });
        // 批量插入班级-课程映射关系
        clazzCourseService.saveBatch(list);
        return true;
    }
}
